先前我們為了專注於 TypeScript 的使用方式,因此元件間的資料傳遞都是透過 props
進行。但隨著元件和功能越來越多,是不是開始覺得資料傳遞變得有些複雜了呢?為了避免 Props Drilling
的問題,今天我們要使用 useContext
和 useReducer
來優化目前的資料管理。
首先,在 src
資料夾下創建一個 store
資料夾,並在裡面新增 TodoContext.tsx
檔案。在現有的專案中,我們在 App.tsx
中匯出了 TodoItem
和 MessageDetails
型別供其他元件使用,現在我們將這些型別移到 TodoContext
,統一在這個檔案中管理。
請將原本在 App.tsx
的 TodoItem
與 MessageDetails
型別複製過來:
export type TodoItem = {
id: number
title: string
isFinished: boolean
}
export type MessageDetails = {
visible: boolean
message: string
mode: 'error' | 'success'
}
刪除原先在這裡定義的 TodoItem
和 MessageDetails
型別,改為從 TodoContext.tsx
匯入:
import { type MessageDetails, type TodoItem } from './store/TodoContext'
更新型別匯入路徑:
import { type TodoItem } from '../store/TodoContext'
同樣地,更新型別匯入路徑:
import { type MessageDetails } from '../store/TodoContext'
接下來,我們在 TodoContext.tsx
中定義現有的新增和刪除功能的 action
:
type ActionType =
| { type: 'ADD_TODO'; payload: string }
| { type: 'DELETE_TODO'; payload: number }
第一次看到這種寫法可能會覺得有點混亂。之前我們所提到的 Union
寫法不應該是這樣嗎:
type ActionType = { type: 'ADD_TODO'; payload: string } | { type: 'DELETE_TODO'; payload: number }
其實,這兩種寫法是完全等值的。在第一項內容前加上 |
是為了更好的排版,提升可讀性。像是使用 Prettier
這種程式碼格式化工具時,它也會自動為我們在第一行加上 |
。
由於 useContext
和 useReducer
對於大多數 React 初學者來說,可能不像 useState
那麼熟悉,因此我們將優化的部分拆成兩篇。在下一篇文章中,我們將使用這兩個 hook
來優化我們的新增和刪除功能。